<template>
  <div>
    <canvas id="canvas2" class="-z-999 fixed top-0 left-0"></canvas>
    <modal msg="🌹🌹我要永远永远永远永远永💖💖远永远永远永远爱你，至死不渝🤪🤪💋💋🌹🌹"></modal>

  </div>
</template>

<script setup>
import { onMounted, onUnmounted } from "vue";
import modal from "./myModal.vue";

const random = function (min, max) {
  return Math.random() * (max - min) + min;
};
const randomColor = function () {
  let colors = [
    "#f44336",
    "#e91e63",
    "#9c27b0",
    "#673ab7",
    "#3f51b5",
    "#2196f3",
    "#03a9f4",
    "#00bcd4",
    "#009688",
    "#4CAF50",
    "#8BC34A",
    "#CDDC39",
    "#FFEB3B",
    "#FFC107",
    "#FF9800",
    "#FF5722",
  ];

  let num = Math.floor(Math.random() * colors.length);
  return colors[num];
};
let canvas;
let ctx;
let _W;
// let _H

class FireWork {
  constructor(x, radius, color, boomPoint) {
    this.x = x;
    this.y = _W;
    this.radius = radius;
    this.color = color;
    this.booms = [];
    this.boomPoint = boomPoint;
    this.boomArea = random(60, 150);
    this.dead = false;
    this.sparkDead = false;
  }

  move() {
    // 与爆炸位置的距离,逐渐变小
    let dx = this.boomPoint.x - this.x;
    let dy = this.boomPoint.y - this.y;
    // 跟随距离改变上升速度,逐渐变慢
    this.x = this.x + dx * 0.01;
    this.y = this.y + dy * 0.01;
    // 后期烟花移动速度过慢,故给一个距离范围,进入范围便爆炸
    if (Math.abs(dx) <= this.boomArea && Math.abs(dy) <= this.boomArea) {
      this.dead = true;
      this.initBoom();
    }
  }

  draw() {
    ctx.save();
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.restore();
  }

  drawTail() {
    ctx.save();
    ctx.fillStyle = "rgba(186,186,86,0.3)";
    ctx.beginPath();
    ctx.arc(this.x, this.y, random(this.radius, this.radius + 4), 0, 2 * Math.PI);
    ctx.fill();
    ctx.restore();
  }

  initBoom() {
    let num = random(50, 200);
    for (let i = 0; i < num; i++) {
      let tan = random(-Math.PI, Math.PI);
      let x = random(0, 250) * Math.cos(tan) + this.x;
      let y = random(0, 250) * Math.sin(tan) + this.y;
      let boom = new Spark(this.x, this.y, random(0, 1), randomColor(), x, y);
      this.booms.push(boom);
    }
  }

  boomAction() {
    let deadNum = 1;
    for (let i = 0; i < this.booms.length; i++) {
      if (!this.booms[i].dead) {
        this.booms[i].update();
      } else {
        deadNum++;
      }
    }
    if (deadNum == this.booms.length) this.sparkDead = true;
  }

  update() {
    if (!this.dead) {
      this.move();
      this.draw();
      this.drawTail();
    } else {
      this.boomAction();
    }
  }
}

class Spark {
  constructor(centerX, centerY, radius, color, dieX, dieY) {
    this.dieX = dieX;
    this.dieY = dieY;
    this.x = centerX;
    this.y = centerY;
    this.dead = false;
    this.centerX = centerX;
    this.centerY = centerY;
    // 火花大小差异化
    this.radius = random(radius, radius + 1);
    this.color = color;
  }
  draw() {
    ctx.save();
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.restore();
  }
  move() {
    // 模拟重力下降
    this.dieY = this.dieY + this.radius / 10;
    let dx = this.dieX - this.x;
    let dy = this.dieY - this.y;
    // 如果距离小于 0.1 则坐标直接等于消失坐标
    this.x = Math.abs(dx) < 0.1 ? this.dieX : this.x + dx * 0.1;
    this.y = Math.abs(dy) < 0.1 ? this.dieY : this.y + dy * 0.1;
    // x 达到消失坐标,则消失
    if (dx == 0 && Math.abs(dy) <= 80) {
      this.dead = true;
    }
  }
  update() {
    if (!this.dead) {
      this.move();
      this.draw();
    }
  }
}

const particles = [];
let oldTime = new Date();

let animation = function () {
  window.requestAnimationFrame(animation);
  // 使用 透明度0.1填充画布,实现烟花拖拽特效
  //   ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
  //   ctx.fillRect(0, 0, canvas.width, canvas.height);
  const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
  gradient.addColorStop(0, "rgba(7, 6, 10, .1)");
  gradient.addColorStop(0.7, "rgba(20, 21, 30, .1)");
  gradient.addColorStop(1, "rgba(123, 153, 211, .1)");
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  // 间隔时间生成烟花
  let newDate = new Date();
  if (newDate - oldTime > random(300, 1500)) {
    let o = new FireWork(random(_W / 4, 0.8 * _W), 3, "#FFF", {
      x: random(_W / 4, 0.8 * _W),
      y: random(50, 200),
    });
    particles.push(o);
    oldTime = newDate;
  }
  // 遍历烟花和删除死亡烟花
  particles.forEach((element, index) => {
    element.update();
    if (element.sparkDead) {
      particles.splice(index, 1);
    }
  });
};

onMounted(() => {
  canvas = document.querySelector("#canvas2");
  ctx = canvas.getContext("2d");
  _W = canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  animation();
});
onUnmounted(() => (animation = () => {}));
</script>
